﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace ChatClient
{
    interface IOutgoingMessageHandler
    {
        void OnMessage(String sender, String receiver, String message);
    }

    class ChatInterfaceItem : Control
    {
        // Private constants

        private const int kMessageBoxHeight = 20;

        private const int kSendButtonWidth = 75;
        private const int kSendButtonHeight = 20;

        private const int kMessageLabelHeight = 20;
        private const int kMessageLabelWidth = 50;
        private const int kMessageLabelTopOffset = 3;

        private const String kMessageLabelText = "Message";
        private const String kSendButtonText = "Send";

        // Private data

        private RichTextBox m_history = null;
        private Label m_messageLabel = null;
        private TextBox m_messageBox = null;
        private Button m_sendButton = null;

        private String m_roomName = "";
        private String m_username = "";
        private IOutgoingMessageHandler m_messageHandler;

        // Constructor

        public ChatInterfaceItem(Control parent, int left, int top, int width, int height, String roomName, String username, IOutgoingMessageHandler messageHandler)
        {
            m_roomName = roomName;
            m_username = username;
            m_messageHandler = messageHandler;

            m_history = new RichTextBox();
            m_history.Parent = this;
            m_history.SetBounds(0, 0, width, height - kMessageBoxHeight);

            m_messageLabel = new Label();
            m_messageLabel.Parent = this;
            m_messageLabel.Text = kMessageLabelText;

            m_messageBox = new TextBox();
            m_messageBox.Parent = this;
            m_messageBox.Text = "";
            m_messageBox.KeyPress += new KeyPressEventHandler((object sender, KeyPressEventArgs e) =>
                {
                    if (e.KeyChar != (char) Keys.Enter)
                    {
                        return;
                    }

                    m_messageHandler.OnMessage(m_username, m_roomName, m_messageBox.Text);
                    m_messageBox.Text = "";
                    m_messageBox.Focus();
                });

            m_sendButton = new Button();
            m_sendButton.Parent = this;
            m_sendButton.Text = kSendButtonText;
            m_sendButton.Click += new EventHandler((object sender, EventArgs e) =>
                {
                    m_messageHandler.OnMessage(m_username, m_roomName, m_messageBox.Text);
                    m_messageBox.Text = "";
                    m_messageBox.Focus();
                });

            this.Parent = parent;
            this.Bounds = new Rectangle(left, top, width, height);
            this.Controls.Add(m_history);
            this.Controls.Add(m_messageLabel);
            this.Controls.Add(m_messageBox);
            this.Controls.Add(m_sendButton);

            this.Resize += new System.EventHandler(OnResize);
        }

        // Public methods

        public void PostOutgoingMessage(String message)
        {
            String prefix = m_username + ": ";
            String body = message + "\n";

            m_history.AppendText(prefix);
            int prefixLength = prefix.Length;
            m_history.Select(m_history.Text.Length - prefixLength, prefixLength);
            m_history.SelectionColor = Color.Blue;
            Font currentSelectionFont = m_history.SelectionFont;
            m_history.SelectionFont = new Font(currentSelectionFont, FontStyle.Bold);
            m_history.Select(m_history.Text.Length, 0);
            m_history.ScrollToCaret();

            m_history.AppendText(body);
            int bodyLength = body.Length;
            m_history.Select(m_history.Text.Length - bodyLength, bodyLength);
            currentSelectionFont = m_history.SelectionFont;
            m_history.SelectionFont = new Font(currentSelectionFont, FontStyle.Regular);
            m_history.SelectionColor = Color.Black;
            m_history.Select(m_history.Text.Length, 0);
            m_history.ScrollToCaret();

            m_messageBox.Focus();
        }

        public void PostIncomingMessage(String sender, String message)
        {
            String prefix = sender + ": ";
            String body = message + "\n";

            m_history.AppendText(prefix);
            int prefixLength = prefix.Length;
            m_history.Select(m_history.Text.Length - prefixLength, prefixLength);
            m_history.SelectionColor = Color.Red;
            Font currentSelectionFont = m_history.SelectionFont;
            m_history.SelectionFont = new Font(currentSelectionFont, FontStyle.Bold);
            m_history.Select(m_history.Text.Length, 0);
            m_history.ScrollToCaret();

            m_history.AppendText(body);
            int bodyLength = body.Length;
            m_history.Select(m_history.Text.Length - bodyLength, bodyLength);
            currentSelectionFont = m_history.SelectionFont;
            m_history.SelectionFont = new Font(currentSelectionFont, FontStyle.Regular);
            m_history.SelectionColor = Color.Black;
            m_history.Select(m_history.Text.Length, 0);
            m_history.ScrollToCaret();
        }

        // Events handlers

        private void OnResize(object sender, EventArgs e)
        {
            m_history.SetBounds(0, 0, Width, Height - kMessageBoxHeight);
            m_messageLabel.SetBounds(0, Height - kMessageLabelHeight + kMessageLabelTopOffset, kMessageLabelWidth, kMessageLabelHeight);
            m_messageBox.SetBounds(kMessageLabelWidth, Height - kMessageBoxHeight, Width - kMessageLabelWidth - kSendButtonWidth, kMessageBoxHeight);
            m_sendButton.SetBounds(kMessageLabelWidth + m_messageBox.Width, Height - kSendButtonHeight, kSendButtonWidth, kSendButtonHeight);
        }
    }
}
